//============================================================================================
/**
 * @file	linear_demo_call.c
 * @brief	リニアデモコール
 * @date	2008.11.21
 * @author	Nozomu Saito
 *
 */
//============================================================================================
#include "common.h"
#include "system/wipe.h"
#include "system/brightness.h"
#include "system/snd_tool.h"

#include "../../field/fieldsys.h"
#include "../../field/field_event.h"
#include "../../field/ev_mapchange.h"
#include "../../field/map_tool.h"
#include "../../field/zonedata.h"
#include "../../field/fieldmap_work.h"
#include "../../field/fld_bgm.h"
#include "../../field/ev_time.h"

#include "linear_demo.h"
#include "linear_demo_call.h"

enum{
	SEQ_FLD_FADE_OUT,
	SEQ_FLD_END_F_PROC,
	SEQ_FLD_CALL_DEMO,
	SEQ_FLD_MAP_JUMP,
	SEQ_FLD_START_F_PROC,
	SEQ_FLD_END,
};

typedef struct F_LINEAR_DEMO_DAT_tag
{
	u8 Seq;				//シーケンサ
	u8 LinearDir;			//デモ方向
	u8 PlayerDir;		//マップ遷移後の自機向き
	u8 dummy;

	int NextZone;		//マップ変移先ゾーン
	int NextX;			//マップ変移先Ｘ
	int NextZ;			//マップ変移先Ｚ
	GLST_DATA LightData;
}F_LINEAR_DEMO_DAT;

static void CallLinearDemo(	FIELDSYS_WORK * fsys,
							const u8 inLinearDir,
							GLST_DATA *inLightDataPtr);

static BOOL LinearDemoEvent(GMEVENT_CONTROL * event);

static BOOL FldLinearDemoEvent(GMEVENT_CONTROL * event);

//----------------------------------------------------------------------------
/**
 * @brief	リニアデモコール
 *
 * @param	fsys		フィールドシステムポインタ
 * @param	inLinearDir	方向
 * @param	inPlayerDir	自機方向
 * @param	inNextZone	次のゾーンＩＤ
 * @param	inNextX		マップ遷移先Ｘ座標
 * @param	inNextZ		マップ遷移先Ｚ座標
 *
 * @return	none
 *
 */
//-----------------------------------------------------------------------------
void LinearDemo_CallDemo(	FIELDSYS_WORK * fsys,
							const u8 inLinearDir,
							const u8 inPlayerDir,
							const int inNextZone,
							const int inNextX,
							const int inNextZ)
{
	F_LINEAR_DEMO_DAT *f_dat;
	BOOL rc;
	TARGET_RECT rect;
	int obj_id;

	int dist;

	f_dat = sys_AllocMemoryLo(HEAPID_WORLD, sizeof(F_LINEAR_DEMO_DAT));

	f_dat->LinearDir = inLinearDir;			//デモ方向
	f_dat->PlayerDir = inPlayerDir;		//マップ遷移後の自機向き
	f_dat->NextZone = inNextZone;		//マップ変移先ゾーン
	f_dat->NextX = inNextX;			//マップ変移先Ｘ
	f_dat->NextZ = inNextZ;			//マップ変移先Ｚ

	//ライト情報取得
	GetGlbLightData( LIGHT_TYPE1, &f_dat->LightData );

	f_dat->Seq = SEQ_FLD_FADE_OUT;
	FieldEvent_Call(fsys->event, FldLinearDemoEvent, f_dat);
}

//----------------------------------------------------------------------------
/**
 * @brief	リニアデモコール
 *
 * @param	fsys			フィールドシステムポインタ
 * @param	inLinearDir		リニア進行方向
 * @param	inLightDataPtr	ライトデータポインタ
 *
 * @return	none
 *
 */
//-----------------------------------------------------------------------------
static void CallLinearDemo(FIELDSYS_WORK * fsys, const u8 inLinearDir, GLST_DATA *inLightDataPtr)
{
	LINEAR_DEMO_DAT *dat;
	dat = sys_AllocMemoryLo(HEAPID_WORLD, sizeof(LINEAR_DEMO_DAT));
	//ライト情報取得
	dat->LightDataPtr = inLightDataPtr;
	dat->Dir = inLinearDir;
	//タイムゾーンから昼夜どちらか判定
	switch( EVTIME_GetTimeZone(fsys) ){
	case TIMEZONE_MORNING:
	case TIMEZONE_NOON:
		dat->TimeType = LINEAR_DEMO_TIME_DAY;
		break;
	case TIMEZONE_EVENING:
	case TIMEZONE_NIGHT:
	case TIMEZONE_MIDNIGHT:
		dat->TimeType = LINEAR_DEMO_TIME_NIGHT;
		break;
	default:
		GF_ASSERT(0);
		dat->TimeType = LINEAR_DEMO_TIME_DAY;
	}
	//男女判定
	dat->Sex = MyStatus_GetMySex( SaveData_GetMyStatus( fsys->savedata ) );
	FieldEvent_Call(fsys->event, LinearDemoEvent, dat);
}

//----------------------------------------------------------------------------
/**
 * @brief	リニアデモイベント
 *
 * @param	event		イベントポインタ
 *
 * @return	BOOL		TRUE:イベント終了　FALSE:イベント継続
 *
 */
//-----------------------------------------------------------------------------
static BOOL LinearDemoEvent(GMEVENT_CONTROL * event)
{
	FIELDSYS_WORK * fsys = FieldEvent_GetFieldSysWork(event);
	LINEAR_DEMO_DAT *dat = FieldEvent_GetSpecialWork(event);
	int *seq = FieldEvent_GetSeqWork(event);
	switch (*seq) {
	case 0:
		//プロセス登録
		LinearDemo_ProcSet( fsys , dat );
		break;
	case 1:
		//サブプロセス終了待ち
		if (FieldEvent_Cmd_WaitSubProcEnd(fsys)) {
			return FALSE;
		}
		break;
	case 2:
		sys_FreeMemoryEz(dat);
		return TRUE;
	}
	(*seq) ++;
	return FALSE;
}

//----------------------------------------------------------------------------
/**
 * @brief	フィールドデモイベント
 *
 * @param	event		イベントポインタ
 *
 * @return	BOOL		TRUE:イベント終了　FALSE:イベント継続
 *
 */
//-----------------------------------------------------------------------------
static BOOL FldLinearDemoEvent(GMEVENT_CONTROL * event)
{
	FIELDSYS_WORK * fsys = FieldEvent_GetFieldSysWork(event);
	F_LINEAR_DEMO_DAT *f_dat = FieldEvent_GetSpecialWork(event);
	switch (f_dat->Seq) {
	case SEQ_FLD_FADE_OUT:
		//ワイプスタート	ブラックアウト
		WIPE_SYS_Start(	WIPE_PATTERN_WMS, WIPE_TYPE_FADEOUT,
							WIPE_TYPE_FADEOUT,0x0,COMM_BRIGHTNESS_SYNC,1,HEAPID_WORLD );
		Snd_BgmFadeOut( 0, COMM_BRIGHTNESS_SYNC );
		f_dat->Seq = SEQ_FLD_END_F_PROC;
		break;
	case SEQ_FLD_END_F_PROC:
		//ワイプ・ＢＧＭフェード終了待ち
		if ( !WIPE_SYS_EndCheck()||(Snd_FadeCheck()!=0) ){
			return FALSE;
		}
		Snd_BgmStop( Snd_NowBgmNoGet(), 0 );				//BGM停止
		//イベントコマンド：フィールドマッププロセス終了
		EventCmd_FinishFieldMap(event);
		f_dat->Seq = SEQ_FLD_CALL_DEMO;
		break;
	case SEQ_FLD_CALL_DEMO:
		//リニアデモコール
		CallLinearDemo(fsys, f_dat->LinearDir, &f_dat->LightData);
		f_dat->Seq = SEQ_FLD_MAP_JUMP;
		break;
	case SEQ_FLD_MAP_JUMP:
		//マップジャンプ
		EventCmd_MapChange(event,
							f_dat->NextZone,
							DOOR_ID_JUMP_CODE,
							f_dat->NextX,
							f_dat->NextZ,
							f_dat->PlayerDir);
		f_dat->Seq = SEQ_FLD_START_F_PROC;
		break;
	case SEQ_FLD_START_F_PROC:
		//Snd_EvMapChangeBgmPlay( fsys, f_dat->NextZone, 1 );	//オーバーレイでev_check.c呼べない
		Snd_EvMapChangeBgmPlay( fsys, f_dat->NextZone, 0 );
		//フィールドプロセス復帰(フェードイン付き)
		EventCmd_StartField_FadeIn(event);
		f_dat->Seq = SEQ_FLD_END;
		break;
	case SEQ_FLD_END:
		sys_FreeMemoryEz(f_dat);
		return TRUE;
	}
	return FALSE;
}